package com.yzcrm.erp.kms.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.aop.Aop;
import com.jfinal.aop.Before;
import com.jfinal.aop.Inject;
import com.jfinal.kit.Kv;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.SqlPara;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.yzcrm.common.config.paragetter.BasePageRequest;
import com.yzcrm.common.constant.BaseConstant;
import com.yzcrm.common.lucene.LuceneIndex;
import com.yzcrm.erp.admin.common.AdminMessageEnum;
import com.yzcrm.erp.admin.entity.AdminField;
import com.yzcrm.erp.admin.entity.AdminMessage;
import com.yzcrm.erp.admin.entity.AdminScene;
import com.yzcrm.erp.admin.service.AdminFieldService;
import com.yzcrm.erp.admin.service.AdminSceneService;
import com.yzcrm.erp.admin.service.AdminUserService;
import com.yzcrm.erp.crm.common.CrmEnum;
import com.yzcrm.erp.crm.service.CrmRecordService;
import com.yzcrm.erp.kms.entity.KmsBbs;
import com.yzcrm.utils.AuthUtil;
import com.yzcrm.utils.BaseUtil;
import com.yzcrm.utils.ParamsUtil;
import com.yzcrm.utils.R;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author jiang.xue
 */
public class KmsBbsService {

    @Inject
    private CrmRecordService crmRecordService;

    @Inject
    private AdminFieldService adminFieldService;

    @Inject
    private AdminSceneService adminSceneService;

    @Inject
    private AdminUserService adminUserService;

    @Inject
    private LuceneIndex luceneIndex;

    /**
     * 追加帖子
     * @param jsonObject
     * @return
     */
    @Before(Tx.class)
    public R addOrUpdate(JSONObject jsonObject) {

//        Log.getLog(KmsBbsService.class).info(jsonObject.toString() + "....");

        KmsBbs kmsBbs = jsonObject.getObject("entity", KmsBbs.class);
        if(ObjectUtil.isNull(kmsBbs)) {
            R.error("参数不正确");
        }
//        Log.getLog(KmsBbsService.class).info(kmsBbs + "....");

        String batchId = StrUtil.isNotEmpty(kmsBbs.getBatchId()) ? kmsBbs.getBatchId() : IdUtil.simpleUUID();
        if(kmsBbs.getBbsId() != null){
            crmRecordService.updateRecord(jsonObject.getJSONArray("field"), batchId);
        }
        adminFieldService.save(jsonObject.getJSONArray("field"), batchId);
        boolean flag;
        if(kmsBbs.getBbsId() != null){

            // 帖子暂时不用审核
            kmsBbs.setCheckStatus(1);
            KmsBbs oldKmsBbs = new KmsBbs().dao().findById(kmsBbs.getBbsId());
            crmRecordService.updateRecord(oldKmsBbs, kmsBbs, CrmEnum.KMS_BBS);
            kmsBbs.setUpdateTime(DateUtil.date());
            kmsBbs.setUpdateUserId(BaseUtil.getUser().getUserId());
            flag = kmsBbs.update();

            // 更新索引
            luceneIndex.updateContent(BaseConstant.LUCENE_PATH_BBS, CrmEnum.KMS_BBS.getType()+"", kmsBbs.getBbsId().toString(), kmsBbs.getTitle(), kmsBbs.getContent());

        }else{

            kmsBbs.setCreateTime(DateUtil.date());
            kmsBbs.setUpdateTime(DateUtil.date());
            kmsBbs.setCreateUserId(BaseUtil.getUser().getUserId());
            kmsBbs.setBatchId(batchId);
            kmsBbs.setCheckStatus(1);// 帖子暂时不用审核
            kmsBbs.setStatus(1);
            kmsBbs.setOwnerUserId(BaseUtil.getUser().getUserId());

            flag = kmsBbs.save();
            crmRecordService.addRecord(kmsBbs.getBbsId().intValue(), CrmEnum.KMS_BBS);

            // 增加消息
            // 检索所有用户
            R r = adminUserService.queryAllUserList(null, new ArrayList<>(), null, null);
            List<Record> listRecord = (List<Record>) r.get("data");//JSONArray.parseArray(r.get("data").toString()).toJavaList(Record.class);
            listRecord.forEach(record -> {

                Long userId = record.getLong("user_id");

                AdminMessage adminMessage = new AdminMessage();
                adminMessage.setTitle(kmsBbs.getTitle());
                adminMessage.setContent(kmsBbs.getContent());
                adminMessage.setLabel(CrmEnum.KMS_BBS.getType());
                adminMessage.setType(AdminMessageEnum.TYPE_OTHER.getType());
                adminMessage.setTypeId(kmsBbs.getBbsId().intValue());
                adminMessage.setCreateUser(BaseUtil.getUserId());
                adminMessage.setCreateTime(DateUtil.date());
                adminMessage.setRecipientUser(userId);
                adminMessage.save();
            });

            // 创建索引
            luceneIndex.addContent(BaseConstant.LUCENE_PATH_BBS, CrmEnum.KMS_BBS.getType()+"", kmsBbs.getBbsId().toString(), kmsBbs.getTitle(), kmsBbs.getContent());

        }

        return flag ? R.ok().put("data", Kv.by("bbs_id", kmsBbs.getBbsId()).set("title", kmsBbs.getTitle())) : R.error();
    }

    /**
     * 获取场景 并 获取帖子列表
     * @param basePageRequest
     * @return
     */
    public R filterConditionAndGetPageList(BasePageRequest basePageRequest){

        JSONObject jsonObject = basePageRequest.getJsonObject();
        Integer sceneId = jsonObject.getInteger("sceneId");
        JSONObject data = new JSONObject();
        if(sceneId != null && sceneId != 0){
            data = JSON.parseObject(AdminScene.dao.findById(sceneId).getData());
        }
        if(sceneId == null && jsonObject.getInteger("type") == 1){
            data = new JSONObject().fluentPut("is_transform", new JSONObject().fluentPut("name", "is_transform").fluentPut("condition", "is").fluentPut("value", "0"));
        }
        if(jsonObject.getJSONObject("data") != null){
            if(data != null){
                data.putAll(jsonObject.getJSONObject("data"));
            }
        }
        jsonObject.put("data",data);
        basePageRequest.setJsonObject(jsonObject);
        return getBbsPageList(basePageRequest);
    }

    /**
     * 获取帖子列表
     * @param basePageRequest
     * @return
     */
    public R getBbsPageList(BasePageRequest basePageRequest) {

        JSONObject jsonObject = basePageRequest.getJsonObject();
        Kv kv = new Kv();
        List<JSONObject> queryList = new ArrayList<>();
        Integer type = jsonObject.getInteger("type");
        boolean isValid = jsonObject.getBoolean("isValid") != null ? jsonObject.getBoolean("isValid") : false;

        //自定义字段列表
        Map<String, AdminField> fieldMap = adminSceneService.getAdminFieldMap(type);

        // 取得场景名称 同label
        String realm = CrmEnum.parse(type).getName();
        if(ObjectUtil.isNull(realm)) {
            return R.error("type不符合要求");
        }

        // 附加检索条件
        JSONObject data = basePageRequest.getJsonObject().getJSONObject("data");
        if (!adminSceneService.appendSqlCondition(kv, fieldMap, queryList, data, type)){
            return R.error("参数包含非法字段");
        }
        String search = basePageRequest.getJsonObject().getString("search");
        if(StrUtil.isNotEmpty(search)){
            if (!adminSceneService.appendSqlSearch(type, queryList, search)){
                return R.error("参数包含非法字段");
            }
            if(!kv.containsKey("fixed")){
                kv.set("fixed",true);
            }
        }

        // 获取排序字段
        String camelField = basePageRequest.getJsonObject().getString("sortField");
        String sortField = StrUtil.toUnderlineCase(camelField);
        String orderNum = basePageRequest.getJsonObject().getString("order");
        if(StrUtil.isEmpty(sortField) || StrUtil.isEmpty(orderNum)){
            kv.set("orderByKey", "update_time").set("orderByType", "desc").set("fieldType", 1);
        }else{
            if(! ParamsUtil.isValid(sortField)){
                return R.error("参数包含非法字段");
            }
            orderNum = "2".equals(orderNum) ? "asc" : "desc";
            kv.set("orderByKey", sortField).set("orderByType", orderNum).set("fieldType", fieldMap.get(sortField) != null ? fieldMap.get(sortField).getFieldType() : 0);
        }

        // 开始生成条件SQL
        StringBuilder conditions = new StringBuilder();

        //获取已审核数据
        if(isValid) {
            conditions.append(" and check_status = 1");
        }

        conditions.append(" and status != 2");

        // 检索权限
        Long userId = BaseUtil.getUserId();
        List<Integer> roles = BaseUtil.getUser().getRoles();
        if(! BaseConstant.SUPER_ADMIN_USER_ID.equals(userId) && !roles.contains(BaseConstant.SUPER_ADMIN_ROLE_ID)){

            String menuRealm = "bbs";

            List<Long> longs = Aop.get(AdminUserService.class).queryUserByAuth(userId, menuRealm);
            if(longs != null && longs.size() > 0){
                conditions.append(" and (a.owner_user_id in (").append(StrUtil.join(",", longs)).append(")");
                conditions.append(")");
            }
        }
        JSONObject sqlObject = new JSONObject();
        sqlObject.put("sql", conditions.toString());
        sqlObject.put("type", 1);
        if(!kv.containsKey("fixed")){
            kv.set("fixed",true);
        }
        queryList.add(sqlObject);

        // 设置分页
        if(StrUtil.isEmpty(basePageRequest.getJsonObject().getString("excel"))){
            kv.set("page", (basePageRequest.getPage() - 1) * basePageRequest.getLimit()).set("limit", basePageRequest.getLimit());
        }

        String selectSql = "select * ";
        List<String> batchList = adminSceneService.queryBatchId(queryList);
        if(batchList.size()==0&&kv.containsKey("field")){
            batchList.add("");
        }
        kv.set("select", selectSql).set("queryList", queryList).set("realm", realm).set("fieldMap", fieldMap).set("label", type);
        kv.set("batchList",batchList);
        SqlPara sqlPara = null;
        if(kv.getInt("fieldType") == 0){
            sqlPara = Db.getSqlPara("kms.bbs.queryBbsPageList2", kv);
        }else{
            sqlPara = Db.getSqlPara("kms.bbs.queryBbsPageList1", kv);
        }

        // 检索数据
        List<Record> recordPage = Db.find(sqlPara);
        recordPage.forEach(record -> {

            Integer isAnonymous = record.getInt("is_anonymous");
            if(ObjectUtil.isNotNull(isAnonymous) && isAnonymous == 1) {
                record.set("create_user_name", "***");
                record.set("owner_user_name", "***");
            }
        });

        JSONObject resultJsonObject = new JSONObject();
        resultJsonObject.put("list", recordPage);
        SqlPara countSql = Db.getSqlPara("kms.bbs.queryBbsPageListCount", kv);
        Integer count = Db.queryInt(countSql.getSql(), countSql.getPara());
        resultJsonObject.put("totalRow", count);
        return R.ok().put("data", resultJsonObject);

    }

    /**
     * 根据帖子id查询
     */
    public Record queryById(Integer bbsId){
        Record record = Db.findFirst(Db.getSql("kms.bbs.queryById"), bbsId);
        List<Record> recordList = Db.find("select name,value from `yzcrm_admin_fieldv` where batch_id = ?", record.getStr("batch_id"));
        recordList.forEach(field -> record.set(field.getStr("name"), field.getStr("value")));
        return record;
    }

    /**
     * 查询编辑字段
     */
    public List<Record> queryField(Integer bbsId){
        Record bbs = queryById(bbsId);
        List<Record> fieldList = adminFieldService.queryUpdateField(CrmEnum.KMS_BBS.getType(), bbs);
        return fieldList;
    }

    /**
     * 根据id删除帖子
     */
    public R deleteByIds(String bbsIds){
        String[] idsArr = bbsIds.split(",");
        List<Record> idsList = new ArrayList<>();
        for(String id : idsArr){

            // 权限判断
            String permissions = "kms:bbs:delete";
            if(!BaseUtil.getUserId().equals(BaseConstant.SUPER_ADMIN_USER_ID) && !BaseUtil.getUser().getRoles().contains(BaseConstant.SUPER_ADMIN_ROLE_ID)
                    && !AuthUtil.isHavaAuth(permissions)
                    && Db.queryInt(Db.getSql("kms.bbs.queryIsOwnerUser"), BaseUtil.getUserId(), id) <= 0){
                return R.error("没有权限");
            }


            // 超过24小时不能删除
            Record recordBbs = this.queryById(Integer.valueOf(id));
            Long subHour = (System.currentTimeMillis() - recordBbs.getDate("create_time").getTime())/1000/60/60;
            if(!BaseUtil.getUserId().equals(BaseConstant.SUPER_ADMIN_USER_ID) && !BaseUtil.getUser().getRoles().contains(BaseConstant.SUPER_ADMIN_ROLE_ID)
                    &&subHour >= BaseConstant.MAX_DELETE_BBS_HOUR) {
                return R.error("已超过"+BaseConstant.MAX_DELETE_BBS_HOUR+"小时无法删除：" + recordBbs.get("title"));
            }


            Record record = new Record();
            idsList.add(record.set("bbs_id", Integer.valueOf(id)));
        }

        List<Record> batchIdList = Db.find(Db.getSqlPara("kms.bbs.queryBatchIdByIds", Kv.by("ids", idsArr)));
        boolean result = Db.tx(() -> {
            Db.batch(Db.getSql("kms.bbs.deleteByIds"), "bbs_id", idsList, 100);
//            Db.batch("delete from yzcrm_admin_fieldv where batch_id = ?", "batch_id", batchIdList, 100);
            return true;
        });

        if(result == true) {

            for(String id : idsArr) {
                // 删除索引
                luceneIndex.deleteContent(BaseConstant.LUCENE_PATH_BBS, id);
            }
        }

        return result ? R.ok() : R.error();
    }

    /**
     * 基本信息
     */
    public List<Record> information(Integer bbsId) {
        Record record = queryById(bbsId);
        List<String> keyList = Arrays.asList("title", "content", "content_type", "business_modular_type");
        List<Record> recordList = adminFieldService.queryInformation(CrmEnum.KMS_BBS, record, keyList);
        return recordList.stream().sorted(Comparator.comparingInt(r->-r.getInt("field_type"))).map(r-> r.remove("field_type","field_name","setting","type")).collect(Collectors.toList());
    }

}
